#include "dtdvalidator.h"

#include <string>
#include <regex> //note : regex is under test, and requires C++11

#include "../AnalyseurXML/src/document.h"
#include "../AnalyseurDTD/src/base_element.h"
#include "../AnalyseurDTD/src/doctype_definition.h"

using namespace std;

static bool validateElement(DoctypeDefinition *dtd, XmlElement *element) {
	bool valide = false;
	
//	list<Node*>* children = element->getChildren();
//	for (list<Node*>::iterator iter = children->begin();
//		 iter != children->end();
//		 ++iter) {
		
		ostringstream ostream;
	
//		(*iter)->print(ostream);
		element->print(ostream);
		string elementStr = ostream.str();
		
		BaseElement* matchDtd = dtd->getElementByName(element->getTag());
		if (matchDtd == NULL) return false; //element has no definition...
		cout << "Comparing xml file with the following regex :\n";
		cout << matchDtd->generateRegex(dtd) << "\n";
		try {
			regex elementRegex (matchDtd->generateRegex(dtd), regex_constants::extended);
			valide = regex_match (elementStr, elementRegex);
		} catch (regex_error& e) {
			cout << "Fuuuuuuuuuuuuuuuuuuuuuuu. Regex generated by DTD file is no regex... error code : ";
			switch (e.code()) {
			case regex_constants::error_collate: cout << "collate" <<"\n";
			break;
			case regex_constants::error_ctype: cout << "char class name" <<"\n";
			break;
			case regex_constants::error_escape: cout << "escape" <<"\n";
			break;
			case regex_constants::error_backref: cout << "back ref" <<"\n";
			break;
			case regex_constants::error_brack: cout << "bracket" <<"\n";
			break;
			case regex_constants::error_paren: cout << "parenthesis" <<"\n";
			break;
			case regex_constants::error_brace: cout << "brace" <<"\n";
			break;
			case regex_constants::error_badbrace: cout << "bad brace" <<"\n";
			break;
			case regex_constants::error_range: cout << "range" <<"\n";
			break;
			case regex_constants::error_space: cout << "space" <<"\n";
			break;
			case regex_constants::error_badrepeat: cout << "badrepeat" <<"\n";
			break;
			case regex_constants::error_complexity: cout << "complexity" <<"\n";
			break;
			case regex_constants::error_stack: cout << "stack" <<"\n";
			break;
			}
		}
		
//		if (!valide) {
//			break;
//		} else {
//			
//		}
//	}
	
	return valide;
}

bool validateDtd(DoctypeDefinition *dtd, Document *document) {

	//ostringstream ostream;
	
	//document->print(ostream);
	//string documentStr = ostream.str();
	XmlElement* root = document->getRoot();
	return validateElement(dtd, root);
}
